import logging
LOG = logging.getLogger()

import uuid
from stock.models import *

class Account(object):
    ''' account '''

    def __init__(self, cash, commision=0):
        ''' constructor '''
        self.__id = self.__generateId()
        self.__holdings = {}
        self.__cash = cash
        self.__commision = commision
        self.__orderHisotry = []
        self.__lastPrice = None

    def __generateId(self):
        ''' generate id '''
        return uuid.uuid4()

    def __addHolding(self, quote, share, price):
        ''' add holding '''
        if quote not in self.__holdings:
            self.__holdings[quote] = [share, price]

        else:
            preShare, prePrice = self.__holdings[quote]
            preValue = preShare * prePrice
            curShare = share + preShare
            curPrice = (share * price + preValue) / curShare
            self.__holdings[quote] = [curShare, curPrice]

    def __reduceHolding(self, quote, share):
        ''' reduce holding '''
        preShare, prePrice = self.__holdings[quote]
        curShare = preShare - share
        self.__holdings[quote] = [curShare, prePrice]
        
        if curShare <= 0 :
          del self.__holdings[quote]

    def updatePrice(self, lastPrice):          
        self.__lastPrice = lastPrice
        
    def execute(self, order):
        ''' execute order'''
        value = self.__getOrderValue(order)
        if order['side'] == 'buy':
            self.__cash = self.__cash - value - self.__commision
            self.__addHolding(order['quote'], order['share'], order['price'])
        else:
            self.__cash = self.__cash + value - self.__commision
            self.__reduceHolding(order['quote'], order['share'])

        self.__orderHisotry.append([self.__cash,order])

    def getCash(self):
        ''' get cash '''
        return self.__cash

    def getHoldingSharebyQuote(self,quote):
      share = 0
      if quote in self.__holdings:
        share = self.__holdings[quote][0]
      return share
      
    def getHoldingCost(self):
        ''' get cost of holdings '''
        value = 0.0
        for share, price in self.__holdings.values():
            value += share * price
            
        return value

    def getHoldingValue(self):
        ''' get value of holdings '''
        value = 0.0
        for quote, (share, price) in self.__holdings.items():
            price = self.__lastPrice[quote]
            value += share * price

        return value

    def getTotalValue(self):
        ''' get total value '''
        return self.getCash() + self.getHoldingValue()

    def __getOrderValue(self, order):
        ''' get value of order '''
        return float(order['price']) * float(order['share'])

    def __getId(self):
        ''' get id '''
        return self.__id

    def __getHoldings(self):
        ''' get holding'''
        return self.__holdings

    def __getOrderHistory(self):
        ''' get order history '''
        return self.__orderHisotry

    def __getCommision(self):
        ''' get commission '''
        return self.__commision

    def __str__(self):
        ''' override string function '''
        totalValue = 0.0
        try:
            totalValue = self.getTotalValue()
        except:
            pass
        return str({'accountId': str(self.accountId), 'holdings': self.holdings, 'cash': self.cash,
                    'totalValue': totalValue, 'holdingCost': self.getHoldingCost()})

    accountId = property(__getId)
    holdings = property(__getHoldings)
    cash = property(getCash)
    orderHistory = property(__getOrderHistory)
    commision = property(__getCommision)
